/**
 * Fork: https://github.com/CreateWheel/mini-i18n
 */
class EventEmitter {
    #events = /* @__PURE__ */ new Map();
    on(event, listener) {
        if (!this.#events.has(event)) {
            this.#events.set(event, /* @__PURE__ */ new Set());
        }
        this.#events.get(event).add(listener);
        return () => {
            this.off(event, listener);
        };
    }
    once(event, listener) {
        const wrapper = (payload) => {
            this.off(event, wrapper);
            listener(payload);
        };
        return this.on(event, wrapper);
    }
    off(event, listener) {
        this.#events.get(event)?.delete(listener);
        if (this.#events.get(event)?.size === 0) {
            this.#events.delete(event);
        }
    }
    emit(event, payload) {
        this.#events.get(event)?.forEach((listener) => listener(payload));
    }
    clear(event) {
        event ? this.#events.delete(event) : this.#events.clear();
    }
}

class I18n extends EventEmitter {
    #defaultLanguage;
    #language;
    #languages;
    #interpolation;
    #interpolationRegExp;
    #cache;
    constructor(options) {
        super();
        this.#defaultLanguage = options.defaultLanguage;
        this.#language = options.language || options.defaultLanguage;
        this.#languages = options.languages;
        this.#interpolation = options.interpolation || {
            prefix: "{",
            suffix: "}"
        };
        this.#interpolationRegExp = this.#initInterpolationRegExp();
        this.#cache = new Map();
    }
    t(key, options) {
        const cacheValue = this.#cache.get(key);
        if (cacheValue) {
            return cacheValue;
        }
        let value = this.#getValue(key);
        if (!value) {
            this.emit("missingKey", {
                key,
                options
            });
            if (options?.defaultValue) {
                return options.defaultValue;
            }
            value = this.#getValue(key, this.#defaultLanguage);
        }
        if (value && options?.params) {
            value = this.#handleInterpolation(value, options.params);
        }
        value = value ?? key;
        this.#cache.set(key, value);
        return value;
    }
    clearCache() {
        this.#cache.clear();
    }
    getLanguage() {
        return this.#language;
    }
    getLanguages() {
        return this.#languages[this.#language];
    }
    setLanguage(language) {
        this.clearCache();
        this.#language = language;
        this.emit("language:changed", {
            language
        });
    }
    addLanguage(language, languageData) {
        this.#languages[language] = languageData;
        this.emit("language:added", {
            language
        });
    }
    #getValue(key, language) {
        const parts = key.split(".");
        let result = this.#languages[language || this.#language];
        for (const part of parts) {
            result = result?.[part];
            if (result === void 0)
                break;
        }
        return result;
    }
    #initInterpolationRegExp() {
        const prefix = this.#interpolation.prefix;
        const suffix = this.#interpolation.suffix;
        const pattern = String.raw`${prefix}(\w+)${suffix}`;
        return new RegExp(pattern, "g");
    }
    #handleInterpolation(value, params) {
        return value.replace(this.#interpolationRegExp, (match, key) => params?.[key] ?? match);
    }
}

export {
    EventEmitter,
    I18n
};